#ifndef __C_CROSSFIRE_SKYBOXNODE_H_
#define __C_CROSSFIRE_SKYBOXNODE_H_

#include "ISceneNode.h"

namespace cfe
{

class CSkyBoxNode : public ICF_SkyBoxNode
{

struct SCF_SkyVertex
{
  D3DXVECTOR3 Point;
  D3DXVECTOR2 UV;

  SCF_SkyVertex( float x, float y, float z, float u, float v )
  {
    Point.x = x;
    Point.y = y;
    Point.z = z;

    UV.x = u;
    UV.y = v;
  }
};

#define SKY_VERTEX_COUNT 24
#define SKY_INDEX_COUNT 36
#define SKY_VERTEX_FVF (D3DFVF_XYZ | D3DFVF_TEX1)

private:
	LPDIRECT3DDEVICE9 m_device;
	LPDIRECT3DTEXTURE9 m_textures[6];
	LPDIRECT3DINDEXBUFFER9 m_indexBuffer;
	LPDIRECT3DVERTEXBUFFER9 m_vertexBuffer;
	ICF_CameraNode* m_cam;
public:
  bool Init(const LPWSTR filenames[], float size)
  {
	  m_device = getSceneManager()->getDrawRenderer()->GetDevice();
	  WCHAR fullpath[ MAX_PATH ];
	  
	  //bad block(need managed texture resource
	  for(int i = 0; i < 6; ++i)
	  {
		  GetFullPathName( filenames[ i ], MAX_PATH, fullpath, NULL );
		  if( FAILED( D3DXCreateTextureFromFile( m_device, fullpath, &this->m_textures[i]) ))
			return false;
	  }	
	  
	  if( FAILED( m_device->CreateVertexBuffer( SKY_VERTEX_COUNT*sizeof(SCF_SkyVertex), 
		  D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &this->m_vertexBuffer, 0)))
		  return false;

	  SCF_SkyVertex* pVertices;
	  m_vertexBuffer->Lock(0, 0, (void**)&pVertices, 0);
	  
	  // right
	  pVertices[0] = SCF_SkyVertex( size, -size,  size, 0.0f, 1.0f);
	  pVertices[1] = SCF_SkyVertex( size,  size,  size, 0.0f, 0.0f);
	  pVertices[2] = SCF_SkyVertex( size,  size, -size, 1.0f, 0.0f);
	  pVertices[3] = SCF_SkyVertex( size, -size, -size, 1.0f, 1.0f);

	  // left
	  pVertices[4] = SCF_SkyVertex(-size, -size, -size, 0.0f, 1.0f);
	  pVertices[5] = SCF_SkyVertex(-size,  size, -size, 0.0f, 0.0f);
	  pVertices[6] = SCF_SkyVertex(-size,  size,  size, 1.0f, 0.0f);
	  pVertices[7] = SCF_SkyVertex(-size, -size,  size, 1.0f, 1.0f);
	  
	  // top
	  pVertices[8]  = SCF_SkyVertex(-size,  size,  size, 0.0f, 1.0f);
	  pVertices[9]  = SCF_SkyVertex(-size,  size, -size, 0.0f, 0.0f); 
	  pVertices[10] = SCF_SkyVertex( size,  size, -size, 1.0f, 0.0f);
	  pVertices[11] = SCF_SkyVertex( size,  size,  size, 1.0f, 1.0f);
	  
	  // bottom
	  pVertices[12] = SCF_SkyVertex(-size, -size, -size, 0.0f, 1.0f);
	  pVertices[13] = SCF_SkyVertex(-size, -size,  size, 0.0f, 0.0f);
	  pVertices[14] = SCF_SkyVertex( size, -size,  size, 1.0f, 0.0f);
	  pVertices[15] = SCF_SkyVertex( size, -size, -size, 1.0f, 1.0f);

	  // back
	  pVertices[16] = SCF_SkyVertex(-size, -size,  size, 0.0f, 1.0f);
	  pVertices[17] = SCF_SkyVertex(-size,  size,  size, 0.0f, 0.0f);
	  pVertices[18] = SCF_SkyVertex( size,  size,  size, 1.0f, 0.0f);
	  pVertices[19] = SCF_SkyVertex( size, -size,  size, 1.0f, 1.0f);

	  // front
	  pVertices[20] = SCF_SkyVertex( size, -size, -size, 0.0f, 1.0f);
	  pVertices[21] = SCF_SkyVertex( size,  size, -size, 0.0f, 0.0f);
	  pVertices[22] = SCF_SkyVertex(-size,  size, -size, 1.0f, 0.0f);
	  pVertices[23] = SCF_SkyVertex(-size, -size, -size, 1.0f, 1.0f);

	  m_vertexBuffer->Unlock();

	  if( m_device->CreateIndexBuffer( SKY_INDEX_COUNT*sizeof(WORD), D3DUSAGE_WRITEONLY,
		  D3DFMT_INDEX16, D3DPOOL_DEFAULT, &this->m_indexBuffer, 0))
		  return false;
	  
	  WORD aIndices[] = {0,1,2, 0,2,3, 4,5,6, 4,6,7, 8,9,10, 8,10,11, 
		  12,13,14, 12,14,15, 16,17,18, 16,18,19, 20,21,22, 20,22,23 };
	  WORD* pIndices;

	  m_indexBuffer->Lock(0, 0, (void**)&pIndices, 0);
	  memcpy( pIndices, aIndices, sizeof(aIndices) );
	  m_indexBuffer->Unlock();
	  
	  return true;
  };
  void render()
  {
	  if(getSceneManager()->getCurrentCamera() != m_cam)
		  m_cam = getSceneManager()->getCurrentCamera();

	  m_device->SetRenderState(D3DRS_LIGHTING, false);
	  m_device->SetRenderState(D3DRS_ZWRITEENABLE, false);
	  m_device->SetRenderState(D3DRS_ZENABLE, false);
	  m_device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
	  m_device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
	  
	  D3DXMATRIX transform;
  
	  D3DXMatrixTranslation(&transform, m_cam->GetPos().x, m_cam->GetPos().y, m_cam->GetPos().z);
	  m_device->SetTransform(D3DTS_WORLD, &transform);

	  m_device->SetFVF( SKY_VERTEX_FVF );
	  m_device->SetStreamSource(0, m_vertexBuffer, 0, sizeof(SCF_SkyVertex));
	  m_device->SetIndices(m_indexBuffer);

	  for(int i = 0; i < 6; ++i)
	  {
		  m_device->SetTexture(0, m_textures[i]);
		  m_device->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, i*4, 4, i*6, 2 );
	  }

	  D3DXMatrixIdentity(&transform);
	  m_device->SetTransform(D3DTS_WORLD, &transform);

	  m_device->SetRenderState(D3DRS_LIGHTING, true);
	  m_device->SetRenderState(D3DRS_ZWRITEENABLE, true);
	  m_device->SetRenderState(D3DRS_ZENABLE, true);
	  m_device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
	  m_device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
  }
  void Destroy()
  {
	  RELEASE_COM(m_textures[0]);
	  RELEASE_COM(m_textures[1]);
	  RELEASE_COM(m_textures[2]);
	  RELEASE_COM(m_textures[3]);
	  RELEASE_COM(m_textures[4]);
	  RELEASE_COM(m_textures[5]);

	  RELEASE_COM(m_indexBuffer);
	  RELEASE_COM(m_vertexBuffer);
  };
};

};


#endif